package jus.poc.prodcons.v2;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.InvalidPropertiesFormatException;
import java.util.Map;
import java.util.Properties;
import jus.poc.prodcons.*;

/**
 * Classe principale permettant de lancer l'application.
 *
 * @author Nunes Thomas <nds.thomas@gmail.com>
 * @author Feng Xu <fengxu1989@gmail.com>
 */
public class TestProdCons extends Simulateur {

    protected final int objectif = 2;        //version de l'objectif
    protected int nbProd;
    protected int nbCons;
    protected int nbBuffer;
    protected int tempsMoyenProduction, deviationTempsMoyenProduction,
            tempsMoyenConsommation, deviationTempsMoyenConsommation,
            nombreMoyenDeProduction, deviationNombreMoyenDeProduction,
            nombreMoyenNbExemplaire, deviationNombreMoyenNbExemplaire;

    public TestProdCons(Observateur observateur) {
        super(observateur);
    }

    @Override
    protected void run() throws Exception {
        SimpleDateFormat formatDate = new SimpleDateFormat("MM/dd/yyyy 'a' HH:mm:ss:S ");
        int messagesEnAntente = 0, messagesEchangés = 0;
        this.init("jus/poc/prodcons/options/option2.xml");
        ProdCons buffer = new ProdCons(nbBuffer);
        //On crée nos producteurs et consommateurs.
        Producteur[] producteurs = new Producteur[nbProd];
        Consommateur[] consommateurs = new Consommateur[nbCons];

        // On initialise nos producteurs et consommateurs.
        for (int i = 0; i < producteurs.length; i++) {
            producteurs[i] = new Producteur(observateur, tempsMoyenProduction,
                    deviationTempsMoyenProduction, buffer, nombreMoyenDeProduction,
                    deviationNombreMoyenDeProduction, i);
            producteurs[i].start();
            messagesEnAntente += producteurs[i].nbMessages;
        }
        for (int i = 0; i < consommateurs.length; i++) {
            consommateurs[i] = new Consommateur(observateur, tempsMoyenConsommation,
                    deviationTempsMoyenConsommation, buffer, i);
            consommateurs[i].setDaemon(true);
            consommateurs[i].start();
        }

        while (messagesEnAntente != messagesEchangés) {
            messagesEchangés = 0;
            for (int i = 0; i < consommateurs.length; i++) {
                messagesEchangés += consommateurs[i].nombreDeMessages();
            }
        }
        System.out.println("\n\n@@@@@@ OBJECTIF" + this.objectif + " @@@@@@");
        System.out.println(" Date de fin: " + formatDate.format(new Date()));
        System.out.println("Nombre de message échangés:" + messagesEchangés);

    }

    /**
     * Retreave the parameters of the application.
     *
     * @param file the final name of the file containing the options.
     */
    protected void init(String file) {
        Properties proprietes = new Properties();
        try {
            proprietes.loadFromXML(ClassLoader.getSystemResourceAsStream(file));
        } catch (InvalidPropertiesFormatException e) {
        } catch (IOException e) {
        }
        Class testProd = getClass();
        for (Map.Entry<Object, Object> entree : proprietes.entrySet()) {
            String key = (String) entree.getKey();
            int value = Integer.parseInt((String) entree.getValue());
            try {
                testProd.getDeclaredField(key).set(this, value);
            } catch (IllegalArgumentException | IllegalAccessException | SecurityException e) {
            } catch (NoSuchFieldException e) {
                System.out.println("Exception: Version non conforme avec les paramètres.");
            }
        }
    }

    public static void main(String[] args) {
        new TestProdCons(new Observateur()).start();
    }
}
